﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Caching;
using ticTacToe.Models;
using ticTacToe.Domain;

namespace ticTacToe.Domain
{
    public class TttService
    {
        
        public  Cache cache;

        public TttService() {
            this.cache = new Cache();
            
        }

        public GameModel startGame(UserModel user1, char mark, UserModel user2)
        {
            GameModel gm = new GameModel();
            TttGame tGame = new TttGame(user1, mark, user2);
            cache.Insert(tGame.getGameId(), tGame);
            gm.gameId = tGame.getGameId();
            gm.board = tGame.gameboard.getBoard();
            gm.moveCount = tGame.gameboard.getPlayCount();
            gm.nextMove = tGame.gameboard.getNextPlayBelongsTo();
            if (mark == 'X')
            {
                gm.player1 = tGame.playerX.getUsername();
                gm.player1Mark = tGame.playerX.getMark();
                gm.player2 = tGame.playerO.getUsername();
                gm.player2Mark = tGame.playerO.getMark();
            }
            else
            {
                gm.player1 = tGame.playerO.getUsername();
                gm.player1Mark = tGame.playerO.getMark();
                gm.player2 = tGame.playerX.getUsername();
                gm.player2Mark = tGame.playerX.getMark();
            }
            return gm;
        }

        public GameModel startBotGame(UserModel user, char mark, int diff)
        {
            Cache c = new Cache();
            GameModel gm = new GameModel();
            TttGame tGame = new TttGame(user, mark, diff);
            c.Insert(tGame.getGameId(), tGame);
            gm.gameId = tGame.getGameId();
            gm.board = tGame.gameboard.getBoard();
            gm.moveCount = tGame.gameboard.getPlayCount();
            gm.nextMove = tGame.gameboard.getNextPlayBelongsTo();
            if (mark == 'X')
            {
                gm.player1 = tGame.playerX.getUsername();
                gm.player1Mark = tGame.playerX.getMark();
                gm.player2 = tGame.playerO.getUsername();
                gm.player2Mark = tGame.playerO.getMark();
            }
            else
            {
                gm.player1 = tGame.playerO.getUsername();
                gm.player1Mark = tGame.playerO.getMark();
                gm.player2 = tGame.playerX.getUsername();
                gm.player2Mark = tGame.playerX.getMark();
            }
            return gm;
        }

        
        public GameModel makeMove(string gameId, int square)
        {
            GameModel gm = new GameModel();
            
            
            return gm;
        }
        public void joinGameService(UserModel user)
        {
           //TBI
            throw new NotImplementedException();
        }
        
        public List<UserModel> getFreePlayers() {
            //TBI
            throw new NotImplementedException();
        }

        public void inviteToPlay(string username) {
            //TBI
            throw new NotImplementedException();
        }

        public void acceptInviteToPlay() {
            //TBI
            throw new NotImplementedException();
        }

        
    }

    
    //"Borrowed" from StackOverflow , mechanism for caching on the Server
    public static class CacheManager
    {
        public static bool Exists
            (string cacheKey, HttpContextBase context)
        {
            return context.Cache[cacheKey] != null;
        }

        public static object Get
            (string cacheKey, HttpContextBase context)
        {
            return context.Cache[cacheKey];
        }

        public static T Get<T>
            (string cacheKey, HttpContextBase context)
            where T : class
        {
            return context.Cache.Get(cacheKey) as T;
        }

        public static T Get<T>
            (string cacheKey, HttpContextBase context, Func<T> getItemCallback)
            where T : class
        {
            T item = Get<T>(cacheKey, context);
            if (item == null)
            {
                item = getItemCallback();
                //by default - caching for 1 day
                if (item != null)
                    context.Cache.Insert(cacheKey, item, null,
                        DateTime.Now.AddDays(1), TimeSpan.Zero);
            }

            return item;
        }

        public static void Save<T>
            (string cacheKey, HttpContextBase context, T value)
            where T : class
        {
            context.Cache.Insert(cacheKey, value);
        }
    }


}